package com.googlecode.maratische.google;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.KeyListener;
import java.sql.SQLException;
import java.util.List;

import javax.swing.DefaultListCellRenderer;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableCellRenderer;

import org.apache.log4j.Logger;

import com.googlecode.maratische.google.gui.CurrentFocusComponent;
import com.googlecode.maratische.google.gui.InfWindowAddOfflineMode;
import com.googlecode.maratische.google.gui.InfWindowCheckNewFeeds;
import com.googlecode.maratische.google.gui.ItemListModel;
import com.googlecode.maratische.google.gui.PopupListenerDisplayPane;
import com.googlecode.maratische.google.gui.WindowTreeAddNewFeeds;
import com.googlecode.maratische.google.listeners.SelectItemListener;
import com.googlecode.maratische.google.model.Feed;

public class ItemsPanelJList extends JScrollPane implements SelectItemListener, CurrentFocusComponent {
	static Logger logger = Logger.getLogger(ItemsPanelJList.class.getName());

	private JTable itemsPanel;
	private InfWindowAddOfflineMode infWindow = null;
	private ItemListModel listModel;

	public ItemsPanelJList(ItemListModel listModel, PopupListenerDisplayPane popupListener) {
		super();
		this.listModel = listModel;
		itemsPanel = new JTable(listModel);
		itemsPanel.addMouseListener(popupListener);
		this.setViewportView(itemsPanel);
		this.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_NEVER);

		itemsPanel.setDefaultRenderer(String.class, new MultiLineCellRenderer());

		this.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				Rectangle rectangle = itemsPanel.getCellRect(itemsPanel.getSelectedRow(), itemsPanel.getSelectedColumn(), false);
				System.out.println("height "+rectangle.height+" width " + rectangle.width+"  x "+rectangle.x+"  y "+rectangle.y);
				ItemsPanelJList.this.getViewport().scrollRectToVisible(rectangle);
				/*From the JTable API call getCellRect() to get the rectangle of a specific
				cell. Then from the JScrollpane instance call:
				scrollpane.getViewPort().scrollRectToVisible( rect )*/
//				itemsPanel.ensureIndexIsVisible(itemsPanel.getSelectedRow());
			}
		});
	}

	public int getSelectedRow() {
		return itemsPanel.getSelectedRow();
	}
	
	public int[] getSelectedRows() {
		return itemsPanel.getSelectedRows();
	}
	
	/*
	 * class MultiLineCellRenderer extends JTextArea implements ListCellRenderer
	 * {
	 * 
	 * public MultiLineCellRenderer() { setLineWrap(true);
	 * setWrapStyleWord(true); setOpaque(true); }
	 * 
	 * @Override public Component getListCellRendererComponent(JList list,
	 * Object value, int index, boolean isSelected, boolean cellHasFocus) { if
	 * (isSelected) { setForeground(list.getSelectionForeground());
	 * setBackground(list.getSelectionBackground()); } else {
	 * setForeground(list.getForeground()); setBackground(list.getBackground());
	 * } setFont(list.getFont()); if (hasFocus) {
	 * setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); if
	 * (table.isCellEditable(row, column)) {
	 * setForeground(UIManager.getColor("Table.focusCellForeground"));
	 * setBackground(UIManager.getColor("Table.focusCellBackground")); } } else
	 * { setBorder(new EmptyBorder(1, 2, 1, 2)); } // this.setContentType(
	 * "text/html" ); this.setText((value == null) ? "" : value.toString());
	 * return this; } }
	 */

	/**
	 * 
	 */
	public void doExpandItems(boolean expand) {
		this.listModel.doExpandItems(expand);
	}

	/**
	 * обновляем конкретный элемент.
	 * 
	 * @param index
	 */
	public void updateItemStringForCurrentItem() {
		((ItemListModel) this.itemsPanel.getModel()).updateItemStringForItem(this.itemsPanel.getSelectedRow());
	}
	
	public void updateItemMarkAsReadCurrentItem() {
		((ItemListModel) this.itemsPanel.getModel()).updateItemMarkAsRead(this.itemsPanel.getSelectedRow());
	}

	public void addListSelectionListener(ListSelectionListener listener) {
		itemsPanel.getSelectionModel().addListSelectionListener(listener);
	}

	public void addKeyListenerForList(KeyListener l) {
		itemsPanel.addKeyListener(l);
	}

	/**
	 * показаваем всплывающее информационное окно, для показа пользователю. мол
	 * добавим ленту, если ее еще ни разу не добавляли и не открывали.
	 */
	public void showInfWindowAddOfflineMode(final Feed selectedFeed) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				if (selectedFeed != null) {
					Point position = itemsPanel.getLocationOnScreen();
					Dimension size = itemsPanel.getVisibleRect().getSize();
					infWindow = new InfWindowAddOfflineMode(selectedFeed, position, size);
				}
			}
		});
	}

	public void showInfWindowCheckNewFeeds(final List<Feed> newFeeds) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				if (newFeeds != null) {
					Point position = itemsPanel.getLocationOnScreen();
					Dimension size = itemsPanel.getVisibleRect().getSize();
					infWindow = new InfWindowCheckNewFeeds(newFeeds, position, size);
				}
			}
		});
	}

	public void showWindowTreeAddNewFeeds() {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				Point position = itemsPanel.getLocationOnScreen();
				Dimension size = itemsPanel.getVisibleRect().getSize();
				try {
					new WindowTreeAddNewFeeds(position, size);
				} catch (SQLException e) {
					MainController.getMainController().showError(e);
				} catch (BaseException e) {
					MainController.getMainController().showError(e);
				}
			}
		});
	}

	/**
	 * возвращает сам JList компонент, необходим для передачи фокуса
	 * 
	 * @return
	 */
	public JComponent getCurrentFocusComponent() {
		return this.itemsPanel;
	}

	/**
	 * если открыто окно с информацией, его надо закрыть, чтобы не мешало
	 */
	public void disableInfWindow() {
		if (infWindow != null) {
			infWindow.dispose();
		}
	}

	/**
	 * смещение курсора влево
	 */
	public void selectLeft() {
		if (canLeft()) {
			disableInfWindow();
			itemsPanel.setRowSelectionInterval(itemsPanel.getSelectedRow() + 1,itemsPanel.getSelectedRow() + 1);
			scrollToVisible();
		}
	}

	public boolean canLeft() {
		return itemsPanel.getSelectedRow() + 1 < ((ItemListModel) itemsPanel.getModel()).getRowCount();
	}

	public void scrollToVisible() {
		// logger.debug("scrollToVisible");
		// this.scrollRectToVisible(this.getVisibleRect());
		itemsPanel.scrollRectToVisible(itemsPanel.getVisibleRect());
	}

	/**
	 * смещение курсора влево
	 */
	public void selectRight() {
		if (canRight()) {
			disableInfWindow();
			itemsPanel.setRowSelectionInterval(itemsPanel.getSelectedRow() - 1,itemsPanel.getSelectedRow() - 1);
			scrollToVisible();
		}
	}

	public boolean canRight() {
		return itemsPanel.getSelectedRow() > 0;
	}

	public int getSelectedIndex() {
		return itemsPanel.getSelectedRow();
	}

	public void clearSelection() {
		if (itemsPanel.getSelectedRow() > -1) {
			itemsPanel.clearSelection();
		}
	}

	@Override
	public void updateUI() {
		super.updateUI();
		if (itemsPanel != null) {
			itemsPanel.updateUI();
		}
	}

	private static final long serialVersionUID = -1380432172605893078L;
}

class MultiLineCellRenderer extends JTextArea implements TableCellRenderer {

	public MultiLineCellRenderer() {
		setLineWrap(true);
		setWrapStyleWord(true);
		setOpaque(true);
	}

	public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

		if (isSelected) {
			setForeground(table.getSelectionForeground());
			setBackground(table.getSelectionBackground());
		} else {
			setForeground(table.getForeground());
			setBackground(table.getBackground());
		}

/*		Font font = table.getFont();
		ItemListModel itemList = (ItemListModel) itemsPanel.getModel();
		if (!itemList.getItem(index).isRead()) {
			setFont(new Font(font.getName(), Font.BOLD, font.getSize()));
		} else {
			setFont(new Font(font.getName(), Font.PLAIN, font.getSize()));
		}*/
		if (hasFocus) {
			setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
			if (table.isCellEditable(row, column)) {
				setForeground(UIManager.getColor("Table.focusCellForeground"));
				setBackground(UIManager.getColor("Table.focusCellBackground"));
			}
		} else {
			setBorder(new EmptyBorder(1, 2, 1, 2));
		}
		setText((value == null) ? "" : value.toString());
		return this;
	}
}